package cn.cool.trigger.http;

import cn.cool.api.IMarketTradeService;
import cn.cool.api.dto.LockMarketPayOrderRequestDTO;
import cn.cool.api.dto.LockMarketPayOrderResponseDTO;
import cn.cool.api.dto.SettlementMarketPayOrderRequestDTO;
import cn.cool.api.dto.SettlementMarketPayOrderResponseDTO;
import cn.cool.api.response.Response;
import cn.cool.domain.activity.model.entity.MarketProductEntity;
import cn.cool.domain.activity.model.entity.TrialBalanceEntity;
import cn.cool.domain.activity.model.valobj.GroupBuyActivityDiscountVO;
import cn.cool.domain.activity.service.IIndexGroupBuyMarketService;
import cn.cool.domain.trade.model.entity.*;
import cn.cool.domain.trade.model.valobj.GroupBuyProgressVO;
import cn.cool.domain.trade.service.ITradeLockOrderService;
import cn.cool.domain.trade.service.ITradeSettlementOrderService;
import cn.cool.types.enums.ResponseCode;
import cn.cool.types.exception.AppException;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/api/v1/gbm/trade/")
@RequiredArgsConstructor
public class MarketTradeController implements IMarketTradeService {
    @Resource
    private IIndexGroupBuyMarketService indexGroupBuyMarketService;
    @Resource
    private ITradeLockOrderService tradeOrderService;
    @Resource
    private ITradeSettlementOrderService tradeSettlementOrderService;

    @Override
    @PostMapping("lock_market_pay_order")
    public Response<LockMarketPayOrderResponseDTO> lockMarketPayOrder(@RequestBody LockMarketPayOrderRequestDTO lockMarketPayOrderRequestDTO) {
        try {
            // 拼团携带参数：userId
            String userId = lockMarketPayOrderRequestDTO.getUserId();
            // 拼团携带参数：商品信息（source、channel、skuId）
            String source = lockMarketPayOrderRequestDTO.getSource();
            String channel = lockMarketPayOrderRequestDTO.getChannel();
            String goodsId = lockMarketPayOrderRequestDTO.getGoodsId();
            // 拼团携带参数：活动id
            Long activityId = lockMarketPayOrderRequestDTO.getActivityId();
            // 拼团携带参数：第三方支付订单 id
            String outTradeNo = lockMarketPayOrderRequestDTO.getOutTradeNo();
            // 拼团携带参数：拼团 id（为空代表开团，不为空代表拼团）
            String teamId = lockMarketPayOrderRequestDTO.getTeamId();
            // 拼团携带参数：上游回调 URL
            String notifyUrl = lockMarketPayOrderRequestDTO.getNotifyUrl();

            log.info("营销交易锁单: {}, lockMarketPayOrderRequestDTO: {}", userId, lockMarketPayOrderRequestDTO);

            if (StrUtil.isBlank(userId) || StrUtil.isBlank(source)
                    || StrUtil.isBlank(channel) || StrUtil.isBlank(goodsId) || activityId == null || StrUtil.isBlank(notifyUrl)) {
                return Response.<LockMarketPayOrderResponseDTO>builder()
                        .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                        .info(ResponseCode.ILLEGAL_PARAMETER.getInfo())
                        .build();
            }

            // hot活动限流
            tradeOrderService.lockMarketPayOrderLimit(String.valueOf(activityId), goodsId);

            MarketPayOrderEntity marketPayOrderEntity = tradeOrderService.queryNoPayMarketPayOrderByOutTradeNo(userId, outTradeNo);
            if (ObjUtil.isNotNull(marketPayOrderEntity)) {
                LockMarketPayOrderResponseDTO lockMarketPayOrderResponseDTO = LockMarketPayOrderResponseDTO.builder()
                        .orderId(marketPayOrderEntity.getOrderId())
                        .deductionPrice(marketPayOrderEntity.getDeductionPrice())
                        .tradeOrderStatus(marketPayOrderEntity.getTradeOrderStatusEnumVO().getCode())
                        .build();

                log.info("交易订单记录存在：{}, lockMarketPayOrderResponseDTO: {}", userId, JSONUtil.toJsonStr(lockMarketPayOrderResponseDTO));
                return Response.<LockMarketPayOrderResponseDTO>builder()
                        .code(ResponseCode.SUCCESS.getCode())
                        .info(ResponseCode.SUCCESS.getInfo())
                        .data(lockMarketPayOrderResponseDTO)
                        .build();
            }

            if (teamId != null) {
                boolean isDone = tradeOrderService.lockMarketPayOrderDone(String.valueOf(activityId), teamId);
                if (isDone) {
                    return Response.<LockMarketPayOrderResponseDTO>builder()
                            .code(ResponseCode.E0006.getInfo())
                            .info(ResponseCode.E0006.getInfo())
                            .build();
                }
            }

            TrialBalanceEntity trialBalanceEntity = indexGroupBuyMarketService.indexMarketTrial(MarketProductEntity.builder()
                    .userId(userId)
                    .source(source)
                    .channel(channel)
                    .goodsId(goodsId)
                    .activityId(activityId)
                    .build());

            GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = trialBalanceEntity.getGroupBuyActivityDiscountVO();

            // 锁单
            marketPayOrderEntity = tradeOrderService.lockMarketPayOrder(
                    UserEntity.builder().userId(userId).build(),

                    PayActivityEntity.builder()
                            .teamId(teamId)
                            .activityId(activityId)
                            .activityName(groupBuyActivityDiscountVO.getActivityName())
                            .startTime(groupBuyActivityDiscountVO.getStartTime())
                            .endTime(groupBuyActivityDiscountVO.getEndTime())
                            .targetCount(groupBuyActivityDiscountVO.getTarget())
                            .validTime(groupBuyActivityDiscountVO.getValidTime())
                            .build(),

                    PayDiscountEntity.builder()
                            .source(source)
                            .channel(channel)
                            .goodsId(goodsId)
                            .goodsName(trialBalanceEntity.getGoodsName())
                            .originalPrice(trialBalanceEntity.getOriginalPrice())
                            .deductionPrice(trialBalanceEntity.getDeductionPrice())
                            .payPrice(trialBalanceEntity.getPayPrice())
                            .outTradeNo(outTradeNo)
                            .notifyUrl(notifyUrl)
                            .build());

            // 返回结果
            return Response.<LockMarketPayOrderResponseDTO>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(LockMarketPayOrderResponseDTO.builder()
                            .orderId(marketPayOrderEntity.getOrderId())
                            .deductionPrice(marketPayOrderEntity.getDeductionPrice())
                            .tradeOrderStatus(marketPayOrderEntity.getTradeOrderStatusEnumVO().getCode())
                            .build())
                    .build();
        } catch (AppException e) {
            log.error("营销交易锁单业务异常:{} LockMarketPayOrderRequestDTO:{}", lockMarketPayOrderRequestDTO.getUserId(), JSONUtil.toJsonStr(lockMarketPayOrderRequestDTO), e);
            return Response.<LockMarketPayOrderResponseDTO>builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();
        } catch (Exception e) {
            log.error("营销交易锁单服务失败:{} LockMarketPayOrderRequestDTO:{}", lockMarketPayOrderRequestDTO.getUserId(), JSONUtil.toJsonStr(lockMarketPayOrderRequestDTO), e);
            return Response.<LockMarketPayOrderResponseDTO>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    @Override
    public Response<SettlementMarketPayOrderResponseDTO> settlementMarketPayOrder(SettlementMarketPayOrderRequestDTO requestDTO) {
        try {
            log.info("营销交易组队结算开始:{}，outTradeNo： {}", requestDTO.getUserId(), requestDTO.getOutTradeNo());

            if (StrUtil.isBlank(requestDTO.getUserId()) || StrUtil.isBlank(requestDTO.getSource()) || StrUtil.isBlank(requestDTO.getChannel())
                    || StrUtil.isBlank(requestDTO.getOutTradeNo()) || ObjUtil.isNull(requestDTO.getOutTradeTime())) {
                return Response.<SettlementMarketPayOrderResponseDTO>builder()
                        .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                        .info(ResponseCode.ILLEGAL_PARAMETER.getInfo())
                        .build();
            }

            TradePaySettlementEntity tradePaySettlementEntity = tradeSettlementOrderService.settlementMarketPayOrder(TradePaySuccessEntity.builder()
                    .userId(requestDTO.getUserId())
                    .source(requestDTO.getSource())
                    .channel(requestDTO.getChannel())
                    .outTradeNo(requestDTO.getOutTradeNo())
                    .outTradeTime(requestDTO.getOutTradeTime())
                    .build());

            SettlementMarketPayOrderResponseDTO responseDTO = SettlementMarketPayOrderResponseDTO.builder()
                    .userId(tradePaySettlementEntity.getUserId())
                    .teamId(tradePaySettlementEntity.getTeamId())
                    .activityId(tradePaySettlementEntity.getActivityId())
                    .outTradeNo(tradePaySettlementEntity.getOutTradeNo())
                    .build();

            // 返回结果
            Response<SettlementMarketPayOrderResponseDTO> response = Response.<SettlementMarketPayOrderResponseDTO>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(responseDTO)
                    .build();

            log.info("营销交易组队结算完成：{}， outTadeNo：{}， response：{}", responseDTO.getUserId(), requestDTO.getOutTradeNo(), JSONUtil.toJsonStr(response));

            return response;
        } catch (AppException e) {
            log.error("营销交易组队结算异常：{} LockMarketPayOrderRequestDTO: {}", requestDTO.getUserId(), JSONUtil.toJsonStr(requestDTO), e);
            return Response.<SettlementMarketPayOrderResponseDTO>builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();
        } catch (Exception e) {
            log.error("营销交易组队结算失败：{} LockMarketPayOrderRequestDTO: {}", requestDTO.getUserId(), JSONUtil.toJsonStr(requestDTO), e);
            return Response.<SettlementMarketPayOrderResponseDTO>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }


}